/*
 * @Author: fisher
 * @Date: 2024-02-05 22:22:43
 * @LastEditors: luthor luthor-li@qq.com
 * @LastEditTime: 2024-03-11 23:55:11
 * @FilePath: \allback\index.js
 * @Description:
 */
require('dotenv').config({
  path:
    process.env.NODE_ENV === 'production'
      ? '.env.production'
      : '.env.development'
})
const Koa = require('koa')
const jwt = require('koa-jwt')
const secret = process.env.JWT_SECRET // 应由环境变量提供
const fs = require('fs')
const path = require('path')
const serve = require('koa-static')
const mount = require('koa-mount')
const Router = require('koa-router')
const bodyParser = require('koa-bodyparser')
const errorHandler = require('./middlewares/errorHandler')
const HttpError = require('./utils/httpError')
const connectDB = require('./db') // 引入数据库连接配置文件
const cors = require('@koa/cors')
const loggingMiddleware = require('./middlewares/loggingMiddleware') // 确保路径匹配您的项目结构
const { initWebSocketServer } = require('./services/wsService')
const http = require('http')
const app = new Koa()
// 设置front文件夹作为静态文件的根目录
const distDirPath = path.join(__dirname, 'front')
app.use(serve(distDirPath))

// 特定中间件用于 '/' 路径
app.use(async (ctx, next) => {
  // 如果请求是 '/' 并且是 GET 请求，则返回 dist/index.html 文件
  if (ctx.path === '/' && ctx.method === 'GET') {
    // koa-static 会自动处理 index.html 文件，因此直接使用 next() 中间件
    await next()
  } else {
    // 对于其他路径，继续处理下去（例如静态资源服务）
    await next()
  }
})
// 跨域配置
app.use(
  cors({
    origin: 'http://127.0.0.1:9528'
  })
)
// 使用日志中间件
app.use(loggingMiddleware)
// 使用错误处理中间件
global.HttpError = HttpError
app.use(errorHandler)
// 使用bodyparser中间件
app.use(bodyParser())
// JWT 错误处理
app.use(async (ctx, next) => {
  return next().catch(err => {
    if (401 == err.status) {
      throw new HttpError('未登录!', 401)
    } else {
      // // 可以在这里添加更多错误处理逻辑，比如记录日志等
      throw err
    }
  })
})
// 添加用于 JWT 验证的中间件
// unless 部分用于指定某些路径或者模式不需要验证 JWT
app.use(
  jwt({ secret }).unless({
    path: [
      /^\/appMsg/,
      /^\/static/,
      /^\/front/,
      /^\/Auth\/login/,
      /^\/Auth\/register/,
      /^\/ueinstance\/msgBySignal/
    ]
  })
)
const staticDirPath = path.join(__dirname, 'public')
// 给静态文件服务设置前缀 '/static'
app.use(mount('/static', serve(staticDirPath)))
// const staticDirPath2 = path.join(__dirname, 'front')
// // 给静态文件服务设置前缀 '/static'
// app.use(mount('/front', serve(staticDirPath2)))
// 创建一个新的总路由器来统一子路由器
const routerAll = new Router()
// 读取路由目录并自动注册每个路由模块
const routesPath = path.join(__dirname, 'routes')
fs.readdirSync(routesPath).forEach(file => {
  // 忽略文件夹和非JS文件
  if (
    fs.statSync(path.join(routesPath, file)).isFile() &&
    file.endsWith('.js')
  ) {
    // 导入路由模块
    const route = require(path.join(routesPath, file))
    // 使用路由模块的basename作为前缀
    const routePrefix = path.basename(file, '.js')
    routerAll.use(`/${routePrefix}`, route.routes(), route.allowedMethods())
  }
})
// 使用总路由器中间件
app.use(routerAll.routes()).use(routerAll.allowedMethods())
// // // 设置根路径的重定向
// app.use(ctx => {
//   if (ctx.path === '/front') {
//     ctx.redirect('/front/index.html')
//   }
//   // 处理其他路径的请求
//   else {
//     ctx.body = 'Hello World!'
//   }
// })
// 链接数据库
connectDB()
// // 创建 HTTP 服务器并交由 Koa 来处理请求
const server = http.createServer(app.callback())
// 初始化 WebSocket 服务
initWebSocketServer(server)
const PORT = process.env.PORT || 3000
server.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`)
})
